package com.dragon.mmochat.service;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import com.dragon.mmochat.MmochatConstant;
import com.dragon.mmochat.MmochatMain;
import com.dragon.mmochat.message.Mmochat_1_1S;
import com.dragon.mmochat.message.Mmochat_1_27S;
import com.dragon.mmochat.model.enumType.MmochatMapGuiderType;
import com.dragon.mmochat.model.enumType.MmochatMapHintType;
import com.dragon.mmochat.model.enumType.MmochatNpcFaceType;
import com.dragon.mmochat.model.enumType.MmochatNpcItemType;
import com.dragon.mmochat.model.enumType.MmochatRoleBmpType;
import com.dragon.mmochat.model.enumType.MmochatRoleStateType;
import com.dragon.mmochat.model.enumType.MmochatServerType;
import com.dragon.mmochat.model.enumType.MmochatWeatherType;
import com.dragon.mmochat.model.map.MmochatMap;
import com.dragon.mmochat.model.map.MmochatMapGuider;
import com.dragon.mmochat.model.map.MmochatMapHint;
import com.dragon.mmochat.model.map.MmochatMapTransPoint;
import com.dragon.mmochat.model.map.MmochatPoint;
import com.dragon.mmochat.model.role.MmochatNpc;
import com.dragon.mmochat.model.role.MmochatPlayer;
import com.dragon.mmochat.util.MmochatUtil;

public class MmochatMapService {
	private static Logger log = LoggerFactory
			.getLogger(MmochatMapService.class);

	public static ScheduledExecutorService rainThread = Executors
			.newScheduledThreadPool(1);

	public static Map<Integer, MmochatMap> maps = new ConcurrentHashMap<Integer, MmochatMap>();

	// 创建比武场地图
	private static void createPkMap() {
		MmochatMap map = new MmochatMap();
		map.setMapId(MmochatConstant.mapId_比武场);
		map.setMapDataId(MmochatConstant.mapDataId_比武场);
		map.setWalkToBattle(false);
		map.setMapName("比武场");
		maps.put(map.getMapId(), map);

		// 比武场传送人
		MmochatNpc npc = new MmochatNpc();
		npc.setNpcId(MmochatConstant.npcId_pkMapNpc1);
		npc.setMapId(map.getMapId());
		npc.setX((short) 220);
		npc.setY((short) 70);
		npc.setName("传送人");
		npc.setBmpType(MmochatRoleBmpType.乞丐);
		npc.setFace(MmochatNpcFaceType.朝左);
		npc.getFunctionItems().add(MmochatNpcItemType.申请进入跨服擂台);
		npc.getFunctionItems().add(MmochatNpcItemType.跨服竞技点说明);
		npc.getFunctionItems().add(MmochatNpcItemType.前往余杭);
		npc.getFunctionItems().add(MmochatNpcItemType.前往江宁);
		npc.getFunctionItems().add(MmochatNpcItemType.前往开封);
		npc.getFunctionItems().add(MmochatNpcItemType.比武场说明);
		map.addNpc(npc);
		MmochatNpcService.npcs.put(npc.getNpcId(), npc);
	}

	// 创建地府地图
	private static void createDiFuMap() {
		MmochatMap map = new MmochatMap();
		map.setMapId(MmochatConstant.mapId_地府);
		map.setMapDataId(MmochatConstant.mapDataId_地府);
		map.setWalkToBattle(true);
		map.setCanTransToFriend(false);
		map.setMapName("地府");
		maps.put(map.getMapId(), map);

		// 地府传送人
		MmochatNpc npc = new MmochatNpc();
		npc.setNpcId(MmochatConstant.npcId_diFuNpc1);
		npc.setMapId(map.getMapId());
		npc.setX((short) 265);
		npc.setY((short) 108);
		npc.setName("传送人");
		npc.setBmpType(MmochatRoleBmpType.乞丐);
		npc.setFace(MmochatNpcFaceType.朝左);
		npc.getFunctionItems().add(MmochatNpcItemType.前往余杭);
		npc.getFunctionItems().add(MmochatNpcItemType.前往江宁);
		npc.getFunctionItems().add(MmochatNpcItemType.前往开封);
		npc.getFunctionItems().add(MmochatNpcItemType.前往地狱一层);
		map.addNpc(npc);
		MmochatNpcService.npcs.put(npc.getNpcId(), npc);
	}

	// 创建跨服擂台地图
	private static void createMultiPkMap() {
		MmochatMap map = new MmochatMap();
		map.setMapId(MmochatConstant.mapId_跨服擂台);
		map.setMapDataId(MmochatConstant.mapDataId_比武场);
		map.setWalkToBattle(false);
		map.setMapName("跨服擂台");
		maps.put(map.getMapId(), map);

		// 比武场NPC
		MmochatNpc npc = new MmochatNpc();
		npc.setNpcId(MmochatConstant.npcId_multiPkMapNpc1);
		npc.setMapId(map.getMapId());
		npc.setX((short) 175);
		npc.setY((short) 101);
		npc.setName("跨服擂台使者");
		npc.setBmpType(MmochatRoleBmpType.乞丐);
		npc.setFace(MmochatNpcFaceType.朝左);
		npc.getFunctionItems().add(MmochatNpcItemType.查询我的竞技点);
		npc.getFunctionItems().add(MmochatNpcItemType.在线玩家竞技榜);
		npc.getFunctionItems().add(MmochatNpcItemType.竞技点输赢规则);
		npc.getFunctionItems().add(MmochatNpcItemType.竞技点兑换称号);
		map.addNpc(npc);
		MmochatNpcService.npcs.put(npc.getNpcId(), npc);
	}

	public MmochatMapService() {
		if (!MmochatMain.openMergeServer) {
			try {
				rainThread.scheduleWithFixedDelay(new checkRain(), 1, 5,
						TimeUnit.MINUTES);

				// 创建比武场地图
				createPkMap();
				// 创建地府地图
				createDiFuMap();
				// 创建跨服擂台地图
				if (MmochatMain.serverType == MmochatServerType.跨服战服务器) {
					createMultiPkMap();
				}

				// 从配置文件初始化地图及固定NPC
				DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
						.newInstance();
				DocumentBuilder docBuilder = docBuilderFactory
						.newDocumentBuilder();

				Document doc = docBuilder.parse(new File("base/map.xml"));

				// normalize text redivsentation
				doc.getDocumentElement().normalize();
				NodeList listOfMap = doc.getElementsByTagName("map");
				int totalMaps = listOfMap.getLength();
				log.debug("map num = " + totalMaps);

				for (int s = 0; s < listOfMap.getLength(); s++) {
					log.debug("开始加载第" + (s + 1) + "个地图...");
					Node firstMapNode = listOfMap.item(s);
					if (firstMapNode.getNodeType() == Node.ELEMENT_NODE) {
						MmochatMap map = new MmochatMap();
						Element firstMapElement = (Element) firstMapNode;

						// 读取mapId
						NodeList mapIdList = firstMapElement
								.getElementsByTagName("mapId");
						String mapIdStr = mapIdList.item(0).getChildNodes()
								.item(0).getNodeValue().trim();
						int mapId = 0;
						try {
							mapId = Integer.parseInt(mapIdStr);
						} catch (Exception e) {
							e.printStackTrace();
							throw new RuntimeException("加载地图时，mapId不是数字,第" + s
									+ "个地图");
						}
						map.setMapId(mapId);

						// mapDataId
						NodeList mapDataIdList = firstMapElement
								.getElementsByTagName("mapDataId");
						if (mapDataIdList != null
								&& mapDataIdList.getLength() > 0) {
							String mapDataIdStr = mapDataIdList.item(0)
									.getChildNodes().item(0).getNodeValue()
									.trim();
							try {
								int mapDataId = Integer.parseInt(mapDataIdStr);
								map.setMapDataId(mapDataId);
							} catch (Exception e) {
								e.printStackTrace();
								throw new RuntimeException(
										"加载地图时，mapDataId不是数字,第" + s + "个地图");
							}
						} else {
							map.setMapDataId(mapId);
						}

						// 读取mapName
						NodeList mapNameList = firstMapElement
								.getElementsByTagName("mapName");
						String mapName = mapNameList.item(0).getChildNodes()
								.item(0).getNodeValue().trim();
						map.setMapName(mapName);

						// 读取是否走动遇怪
						NodeList hasMonsterList = firstMapElement
								.getElementsByTagName("hasMonster");
						if (hasMonsterList.getLength() > 0) {
							String hasMonster = hasMonsterList.item(0)
									.getChildNodes().item(0).getNodeValue()
									.trim();
							if (hasMonster.endsWith("false")) {
								map.setWalkToBattle(false);
							} else {
								map.setWalkToBattle(true);
							}
						} else {
							map.setWalkToBattle(true);
						}

						// 读取是否能下雨
						NodeList canRainList = firstMapElement
								.getElementsByTagName("canRain");
						if (canRainList.getLength() > 0) {
							String canRain = canRainList.item(0)
									.getChildNodes().item(0).getNodeValue()
									.trim();
							if (canRain.endsWith("true")) {
								map.setHasWeather(true);
							} else {
								map.setHasWeather(false);
							}
						}

						// 读取是否允许好友传送
						NodeList canTransToFriendList = firstMapElement
								.getElementsByTagName("canTransToFriend");
						if (canTransToFriendList.getLength() > 0) {
							String canTransToFriend = canTransToFriendList
									.item(0).getChildNodes().item(0)
									.getNodeValue().trim();
							if (canTransToFriend.endsWith("false")) {
								map.setCanTransToFriend(false);
							} else {
								map.setCanTransToFriend(true);
							}
						} else {
							map.setCanTransToFriend(true);
						}

						// 读取地图守护神信息
						NodeList mapGuiderList = firstMapElement
								.getElementsByTagName("guider");
						if (mapGuiderList != null
								&& mapGuiderList.getLength() > 0) {
							Node firstNode = mapGuiderList.item(0);
							if (firstNode.getNodeType() == Node.ELEMENT_NODE) {
								MmochatMapGuider guider = new MmochatMapGuider();
								Element firstElement = (Element) firstNode;
								// 读取x
								{
									NodeList nodeList = firstElement
											.getElementsByTagName("x");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									int num = 0;
									try {
										num = Integer.parseInt(str.trim());
									} catch (Exception e) {
										e.printStackTrace();
										throw new RuntimeException(
												"加载地图时，hint的x不是数字,mapId="
														+ map.getMapId());
									}
									guider.setX(num);
								}
								// 读取y
								{
									NodeList nodeList = firstElement
											.getElementsByTagName("y");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									int num = 0;
									try {
										num = Integer.parseInt(str.trim());
									} catch (Exception e) {
										e.printStackTrace();
										throw new RuntimeException(
												"加载地图时，hint的y不是数字,mapId="
														+ map.getMapId());
									}
									guider.setY(num);
								}
								// 读取face
								{
									NodeList nodeList = firstElement
											.getElementsByTagName("face");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									MmochatNpcFaceType face = MmochatNpcFaceType
											.valueOf(str);
									guider.setFace(face);
								}
								// 读取myLevel
								{
									NodeList nodeList = firstElement
											.getElementsByTagName("myLevel");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									int num = 0;
									try {
										num = Integer.parseInt(str.trim());
									} catch (Exception e) {
										e.printStackTrace();
										throw new RuntimeException(
												"加载地图时，hint的x不是数字,mapId="
														+ map.getMapId());
									}
									guider.setMyLevel(num);
								}
								// 读取minLevel
								{
									NodeList nodeList = firstElement
											.getElementsByTagName("minLevel");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									int num = 0;
									try {
										num = Integer.parseInt(str.trim());
									} catch (Exception e) {
										e.printStackTrace();
										throw new RuntimeException(
												"加载地图时，hint的x不是数字,mapId="
														+ map.getMapId());
									}
									guider.setMinLevel(num);
								}
								// 读取maxLevel
								{
									NodeList nodeList = firstElement
											.getElementsByTagName("maxLevel");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									int num = 0;
									try {
										num = Integer.parseInt(str.trim());
									} catch (Exception e) {
										e.printStackTrace();
										throw new RuntimeException(
												"加载地图时，hint的y不是数字,mapId="
														+ map.getMapId());
									}
									guider.setMaxLevel(num);
								}
								// 读取lifeTurn转生次数
								{
									NodeList nodeList = firstElement
											.getElementsByTagName("lifeTurn");
									if (nodeList != null
											&& nodeList.getLength() > 0) {
										String str = nodeList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										int num = 0;
										try {
											num = Integer.parseInt(str.trim());
										} catch (Exception e) {
											e.printStackTrace();
											throw new RuntimeException(
													"加载地图时，lifeTurn不是数字,mapId="
															+ map.getMapId());
										}
										guider.setLifeTurnNeed(num);
									}
								}
								// 读取type
								{
									NodeList nodeList = firstElement
											.getElementsByTagName("type");
									if (nodeList != null
											&& nodeList.getLength() > 0) {
										String str = nodeList.item(0)
												.getChildNodes().item(0)
												.getNodeValue().trim();
										MmochatMapGuiderType type = MmochatMapGuiderType
												.valueOf(str);
										if (type != null) {
											guider.setType(type);
										}
									}
								}
								map.setMapGuiderInfo(guider);
							}
						}

						// 读取地图提示语
						NodeList hintList = firstMapElement
								.getElementsByTagName("hint");
						for (int t = 0; t < hintList.getLength(); t++) {
							Node firstHintNode = hintList.item(t);
							if (firstHintNode.getNodeType() == Node.ELEMENT_NODE) {
								MmochatMapHint hint = new MmochatMapHint();
								Element firstElement = (Element) firstHintNode;
								// 读取x
								{
									NodeList nodeList = firstElement
											.getElementsByTagName("x");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									int num = 0;
									try {
										num = Integer.parseInt(str.trim());
									} catch (Exception e) {
										e.printStackTrace();
										throw new RuntimeException(
												"加载地图时，hint的x不是数字,mapId="
														+ map.getMapId());
									}
									hint.setX(num);
								}
								// 读取y
								{
									NodeList nodeList = firstElement
											.getElementsByTagName("y");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									int num = 0;
									try {
										num = Integer.parseInt(str.trim());
									} catch (Exception e) {
										e.printStackTrace();
										throw new RuntimeException(
												"加载地图时，hint的y不是数字,mapId="
														+ map.getMapId());
									}
									hint.setY(num);
								}
								// 读取type
								{
									NodeList nodeList = firstElement
											.getElementsByTagName("type");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									MmochatMapHintType type = MmochatMapHintType
											.valueOf(str);
									hint.setType(type);
								}
								// 读取msg
								{
									NodeList nodeList = firstElement
											.getElementsByTagName("msg");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									hint.setHint("<" + str + ">");
								}
								map.getHints().add(hint);
							}
						}

						// 读取传送口列表
						NodeList transList = firstMapElement
								.getElementsByTagName("trans");
						for (int t = 0; t < transList.getLength(); t++) {
							Node firstTransNode = transList.item(t);
							if (firstTransNode.getNodeType() == Node.ELEMENT_NODE) {
								MmochatMapTransPoint transPoint = new MmochatMapTransPoint();
								Element firstTransElement = (Element) firstTransNode;
								// 读取x
								{
									NodeList nodeList = firstTransElement
											.getElementsByTagName("x");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									int num = 0;
									try {
										num = Integer.parseInt(str.trim());
									} catch (Exception e) {
										e.printStackTrace();
										throw new RuntimeException(
												"加载地图时，传送口的x不是数字,mapId="
														+ map.getMapId());
									}
									transPoint.setX(num);
								}
								// 读取y
								{
									NodeList nodeList = firstTransElement
											.getElementsByTagName("y");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									int num = 0;
									try {
										num = Integer.parseInt(str.trim());
									} catch (Exception e) {
										e.printStackTrace();
										throw new RuntimeException(
												"加载地图时，传送口的y不是数字,mapId="
														+ map.getMapId());
									}
									transPoint.setY(num);
								}
								// 读取nextMapId
								{
									NodeList nodeList = firstTransElement
											.getElementsByTagName("nextMapId");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									int num = 0;
									try {
										num = Integer.parseInt(str.trim());
									} catch (Exception e) {
										e.printStackTrace();
										throw new RuntimeException(
												"加载地图时，传送口的nextMapId不是数字,mapId="
														+ map.getMapId());
									}
									transPoint.setTransToMapId(num);
								}
								// 读取nextX
								{
									NodeList nodeList = firstTransElement
											.getElementsByTagName("nextX");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									int num = 0;
									try {
										num = Integer.parseInt(str.trim());
									} catch (Exception e) {
										e.printStackTrace();
										throw new RuntimeException(
												"加载地图时，传送口的nextX不是数字,mapId="
														+ map.getMapId());
									}
									transPoint.setNewMapX(num);
								}
								// 读取nextY
								{
									NodeList nodeList = firstTransElement
											.getElementsByTagName("nextY");
									String str = nodeList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									int num = 0;
									try {
										num = Integer.parseInt(str.trim());
									} catch (Exception e) {
										e.printStackTrace();
										throw new RuntimeException(
												"加载地图时，传送口的nextY不是数字,mapId="
														+ map.getMapId());
									}
									transPoint.setNewMapY(num);
								}
								map.getTransPoints().add(transPoint);
							}
						}

						// 读取npc列表
						NodeList npcList = firstMapElement
								.getElementsByTagName("npc");

						for (int t = 0; t < npcList.getLength(); t++) {
							log.debug("开始加载mapId=" + map.getMapId() + "的第"
									+ (t + 1) + "个NPC!");
							Node firstNpcNode = npcList.item(t);
							if (firstNpcNode.getNodeType() == Node.ELEMENT_NODE) {
								MmochatNpc npc = new MmochatNpc();
								Element firstNpcElement = (Element) firstNpcNode;

								// 设置NPC所在地图
								npc.setMapId(mapId);

								// 读取npcId
								NodeList npcIdList = firstNpcElement
										.getElementsByTagName("npcId");
								String npcIdStr = npcIdList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								int npcId;
								try {
									npcId = Integer.parseInt(npcIdStr);
								} catch (Exception e) {
									e.printStackTrace();
									throw new RuntimeException(
											"加载地图时，npcId不是数字,mapId="
													+ map.getMapId() + ",第" + t
													+ "个NPC");
								}
								npc.setNpcId(npcId);

								// 读取x坐标
								NodeList xList = firstNpcElement
										.getElementsByTagName("x");
								String xStr = xList.item(0).getChildNodes()
										.item(0).getNodeValue().trim();
								int x;
								try {
									x = Integer.parseInt(xStr);
								} catch (Exception e) {
									e.printStackTrace();
									throw new RuntimeException(
											"加载地图时，npc坐标不是数字,npcId="
													+ npc.getNpcId());
								}
								npc.setX((short) x);

								// 读取y坐标
								NodeList yList = firstNpcElement
										.getElementsByTagName("y");
								String yStr = yList.item(0).getChildNodes()
										.item(0).getNodeValue().trim();
								int y;
								try {
									y = Integer.parseInt(yStr);
								} catch (Exception e) {
									e.printStackTrace();
									throw new RuntimeException(
											"加载地图时，npc坐标不是数字,npcId="
													+ npc.getNpcId());
								}
								npc.setY((short) y);

								// 读取bmpType
								NodeList bmpIdList = firstNpcElement
										.getElementsByTagName("bmp");
								String bmpIdStr = bmpIdList.item(0)
										.getChildNodes().item(0).getNodeValue()
										.trim();
								try {
									npc.setBmpType(MmochatRoleBmpType
											.valueOf(bmpIdStr));
								} catch (Exception e) {
									e.printStackTrace();
									throw new RuntimeException(
											"加载地图时，npc的bmpType非法,npcId="
													+ npc.getNpcId());
								}

								// 读取face
								NodeList faceList = firstNpcElement
										.getElementsByTagName("face");
								if (faceList.getLength() > 0) {
									String faceStr = faceList.item(0)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									try {
										npc.setFace(MmochatNpcFaceType
												.valueOf(faceStr));
									} catch (Exception e) {
										e.printStackTrace();
										throw new RuntimeException(
												"加载地图时，npc的face非法,npcId="
														+ npc.getNpcId());
									}
								}

								// 读取name
								NodeList nameList = firstNpcElement
										.getElementsByTagName("name");
								String name = nameList.item(0).getChildNodes()
										.item(0).getNodeValue().trim();
								npc.setName(name);

								// 读取NPC功能
								NodeList itemList = firstNpcElement
										.getElementsByTagName("item");
								for (int j = 0; j < itemList.getLength(); j++) {
									String msg = itemList.item(j)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									MmochatNpcItemType type = MmochatNpcItemType
											.valueOf(msg);
									npc.getFunctionItems().add(type);
								}

								// 读取默认对话msg
								NodeList msgList = firstNpcElement
										.getElementsByTagName("msg");
								for (int j = 0; j < msgList.getLength(); j++) {
									String msg = msgList.item(j)
											.getChildNodes().item(0)
											.getNodeValue().trim();
									npc.addDefaultMsg(msg);
								}
								map.addNpc(npc);
								if (MmochatNpcService.npcs.containsKey(npc
										.getNpcId())) {
									MmochatNpc otherNpc = MmochatNpcService.npcs
											.get(npc.getNpcId());
									if (otherNpc != null) {
										throw new RuntimeException("npc Id 重复!"
												+ map.getMapName() + "<"
												+ npc.getName() + ">与另一NPC：<"
												+ otherNpc.getName() + ">ID重复。");
									}
								}
								MmochatNpcService.npcs.put(npc.getNpcId(), npc);
							}
						}
						/*************************** 读取边界数据 **************************/
						String fileName = "bound/" + map.getMapDataId()
								+ ".bound";
						File file = new File(fileName);
						log.debug("开始读取边界数据:" + fileName);
						if (file.exists()) {
							if (file.isFile()) {
								try {
									map.getBounds().clear();
									BufferedReader reader = new BufferedReader(
											new FileReader(file));
									String lineBuf;
									while ((lineBuf = reader.readLine()) != null) {
										String[] array = lineBuf.trim().split(
												",");
										if (array != null && array.length > 0) {
											List<Integer> lineBound = new ArrayList<Integer>();
											for (int i = 0; i < array.length; i++) {
												if (array[i].trim() == "") {
													continue;
												}
												try {
													int value = Integer
															.parseInt(array[i]
																	.trim());
													if (value != 0
															&& value != 1
															&& value != 2) {
														throw new RuntimeException(
																"边界数据值非0,1,2!文件名:"
																		+ fileName);
													}
													lineBound.add(value);
												} catch (NumberFormatException e) {
													e.printStackTrace();
													throw new RuntimeException(
															"边界数据值有非数字!文件名:"
																	+ fileName);
												}
											}
											if (lineBound.size() > 0) {
												map.getBounds().add(lineBound);
											}
										}
									}
								} catch (FileNotFoundException e) {
									e.printStackTrace();
									throw new RuntimeException("边界数据文件缺失!文件名:"
											+ fileName);
								} catch (IOException e) {
									e.printStackTrace();
									throw new RuntimeException("边界数据读取出错!文件名:"
											+ fileName);
								}
							} else {
								throw new RuntimeException("边界数据文件缺失!文件名:"
										+ fileName);
							}
						} else {
							log.debug("边界数据文件缺失!文件名:" + fileName);
							// throw new RuntimeException("边界数据文件缺失!文件名:" +
							// fileName);
						}
						if (maps.containsKey(map.getMapId())) {
							MmochatMap otherMap = maps.get(map.getMapId());
							if (otherMap != null) {
								throw new RuntimeException(map.getMapName()
										+ "的地图ID与" + otherMap.getMapName()
										+ "重复。");
							}
						}
						maps.put(map.getMapId(), map);
					}// end of if clause
				}// end of for loop with s var
				log.debug("地图初始化成功!");
			} catch (SAXParseException err) {
				log.debug("** Parsing error" + ", line " + err.getLineNumber()
						+ ", uri " + err.getSystemId());
				log.debug(" " + err.getMessage());
				throw new RuntimeException("地图初始化失败,请重启!");
			} catch (SAXException e) {
				Exception x = e.getException();
				((x == null) ? e : x).printStackTrace();
				throw new RuntimeException("地图初始化失败,请重启!");
			} catch (Throwable t) {
				t.printStackTrace();
				throw new RuntimeException("地图初始化失败,请重启!");
			}
		}
	}

	class checkRain implements Runnable {
		@SuppressWarnings("deprecation")
		@Override
		public void run() {
			try {
				log.debug("check Rain");
				Date now = new Date();
				for (MmochatMap map : maps.values()) {
					try {
						if (map.isHasWeather()) {
							if (map.getCurWeather() != MmochatWeatherType.晴天) {
								// 已经在下雨或下雪等天气中了
								if (System.currentTimeMillis()
										- map.getStartRainTick() >= map
										.getRainKeepTime()) {
									// 天气可以停了
									log.debug(map.getMapName() + "天气停了!");
									map.setCurWeather(MmochatWeatherType.晴天);
									map.setStartRainTick(0);
									map.setRainKeepTime(0);
									// 向此地图所有玩家更新天气状态
									Mmochat_1_27S pack = new Mmochat_1_27S();
									pack.setMap(map);
									for (int line = 0; line < MmochatConstant.maxMapLineNum; line++) {
										for (MmochatPlayer me : map
												.getLineRoleMap(line).values()) {
											if (me != null) {
												MmochatUtil.sendCommonPack(me,
														pack);
											}
										}
									}
								}
							} else if (map.getCurWeather() == MmochatWeatherType.晴天) {
								// 平均每隔6小时下一次雨,1/72的概率发生天气变化
								// 每次天气持续时间:20~40分钟
								int v = (int) (Math.random() * 72);
								if (v == 0) {
									if (now.getMonth() == 10
											|| now.getMonth() == 11
											|| now.getMonth() == 0
											|| now.getMonth() == 1) {
										// 11月、12月、1月、2月可能下雪
										// 50%机率下雪
										if (MmochatUtil.isInPercent(50)) {
											map
													.setCurWeather(MmochatWeatherType.下雪);
										} else {
											map
													.setCurWeather(MmochatWeatherType.下雨);
										}
									} else {
										// 下雨
										map
												.setCurWeather(MmochatWeatherType.下雨);
									}
									map.setStartRainTick(System
											.currentTimeMillis());
									long keepTime = MmochatUtil.getRandomValue(
											20, 40)
											* MmochatConstant.MS_PER_MINUTE;
									map.setRainKeepTime(keepTime);
									log
											.debug(map.getMapName()
													+ "开始产生天气，将持续"
													+ (keepTime / MmochatConstant.MS_PER_MINUTE)
													+ "分钟");
									// 向此地图所有玩家更新天气状态
									Mmochat_1_27S pack = new Mmochat_1_27S();
									pack.setMap(map);
									for (int line = 0; line < MmochatConstant.maxMapLineNum; line++) {
										for (MmochatPlayer me : map
												.getLineRoleMap(line).values()) {
											if (me != null) {
												MmochatUtil.sendCommonPack(me,
														pack);
											}
										}
									}
								}
							}
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	// 是否在比武场内
	public static boolean isInZhangJiPkRange(MmochatPlayer me) {
		if (me == null) {
			return false;
		}
		int x = me.getX();
		int y = me.getY();
		if (me.getMapId() != MmochatConstant.mapId_比武场
				&& me.getMapId() != MmochatConstant.mapId_跨服擂台) {
			return false;
		}
		if (141 * x + 288 * y - 75744 >= 0 && 35 * x - 72 * y + 22608 >= 0
				&& 129 * x - 262 * y - 5188 <= 0
				&& 133 * x + 267 * y - 159522 <= 0) {
			return true;
		}
		return false;
	}

	// 获取地图
	public static MmochatMap getMapByMapId(int mapId) {
		MmochatMap map = maps.get(mapId);
		if (map == null) {
			// TODO:地图不存在
			log.debug("地图不存在,mapId=" + mapId);
			return null;
		}
		return map;
	}

	// 获取随机可到达坐标
	public static MmochatPoint getRandReachablePoint(int mapId) {
		MmochatMap curMap = maps.get(mapId);
		if (curMap == null) {
			return null;
		}
		MmochatPoint point = new MmochatPoint();
		int rowNum = curMap.getBounds().size();
		if (rowNum == 0) {
			return null;
		}
		List<Integer> firstLine = curMap.getBounds().get(0);
		int colNum;
		if (firstLine == null) {
			return null;
		}
		colNum = firstLine.size();
		if (colNum == 0) {
			return null;
		}
		int startRow = (int) (Math.random() * rowNum);
		int startCol = (int) (Math.random() * colNum);
		for (int i = 0; i < rowNum; i++) {
			int curRow = (startRow + i) % rowNum;
			if (rowNum > 4) {
				if (curRow == 0) {
					// 不取第一行
					continue;
				}
			}
			List<Integer> curLine;
			try {
				curLine = curMap.getBounds().get(curRow);
			} catch (Exception e1) {
				e1.printStackTrace();
				continue;
			}
			for (int j = 0; j < colNum; j++) {
				int curCol = (startCol + j) % colNum;
				if (colNum > 4) {
					if (curCol == 0 || curCol == colNum - 1) {
						// 不取第一列和最后一列
						continue;
					}
				}
				try {
					Integer bound = curLine.get(curCol);
					if (bound == 0) {
						point.setX((short) curCol);
						point.setY((short) curRow);
						return point;
					}
				} catch (Exception e) {
					e.printStackTrace();
					continue;
				}
			}
		}
		return null;
	}

	// 将一个玩家切换地图
	public static void tranToNewMap(MmochatMap curMap, int curLine,
			MmochatMap newMap, int newLine, int newX, int newY, MmochatPlayer me) {
		List<MmochatPlayer> members = new ArrayList<MmochatPlayer>();
		members.add(me);
		tranToNewMap(curMap, curLine, newMap, newLine, newX, newY, members);
	}

	// 将一队玩家切换地图
	public static void tranToNewMap(MmochatMap curMap, int curLine,
			MmochatMap newMap, int newLine, int newX, int newY,
			List<MmochatPlayer> members) {
		// 将本队人马传到新地图新坐标
		for (MmochatPlayer member : members) {
			// TODO:其它处理

			if (!member.lockState(MmochatRoleStateType.切换地图时)) {
				log.debug("玩家" + member.getName() + "(skyid="
						+ member.getSkyId() + ")当前状态为<"
						+ member.getState().toString() + ">,无法传送");
				continue;
			}
			if (member.isInBattle()) {
				member.unLockState();
				continue;
			}

			// 停止交易
			member.stopDeal();

			// 清除周围玩家
			member.getSceenRoles().clear();

			// 清除坐标缓存器
			member.getPositionBuffer().clear();

			// 清除NPC列表
			member.getTmpNpcs().clear();

			// 从旧的地图中移除
			if (curMap != null) {
				curMap.delRole(curLine, member);
			}

			// 设置新坐标
			member.setX(newX);
			member.setY(newY);
			member.setMapId(newMap.getMapId());

			member.unLockState();

			log.debug("x=" + member.getX() + ",y=" + member.getY() + ",mapId="
					+ newMap.getMapId() + ",newMapId=" + newMap.getMapId());

			Mmochat_1_1S pack = new Mmochat_1_1S();
			// 不使用hallState进行判断,以免终端连续上传两次请求后,终端hallState被第二次请求发送时更改
			pack.setMap(newMap);
			pack.setLine((int) newLine);
			pack.setMe(member);
			MmochatMainService
					.enterGame(member, member.getUserConnInfo(), pack);
			member.setX(newX);
			member.setY(newY);
			MmochatUtil.sendCommonPack(member, pack);

			if (curMap == null || curMap.getMapId() != newMap.getMapId()
					|| curLine != newLine) {
				try {
					MmochatDao.updateRoleEnterNewMap(member);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
}
